﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Xml;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using DBService;
using YArchitech.LIB;
using YArchitech.ProgressBar;
using YArchitech.Revit.MEP.Opening.Common;
using YArchitech.Revit.RevitExtension;
using HYRMEOpening;

namespace YArchitech.Revit.MEP.Opening
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class CmdOpeningToDb : IExternalCommand
	{
		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		private void OnFailuresProcessing(object sender, FailuresProcessingEventArgs e)
		{
			FailuresAccessor failuresAccessor = e.GetFailuresAccessor();
			string transactionName = failuresAccessor.GetTransactionName();
			IList<FailureMessageAccessor> failureMessages = failuresAccessor.GetFailureMessages();
			if (failureMessages.Count == 0)
			{
				e.SetProcessingResult((FailureProcessingResult)0);
				return;
			}
			if (transactionName.Equals("CreateOpening"))
			{
				foreach (FailureMessageAccessor failureMessageAccessor in failureMessages)
				{
					failuresAccessor.DeleteWarning(failureMessageAccessor);
				}
				e.SetProcessingResult((FailureProcessingResult)1);
				return;
			}
			e.SetProcessingResult((FailureProcessingResult)0);
		}

		public Result Execute(ExternalCommandData cmdData, ref string messages, ElementSet elements)
		{
			Result result;
			try
			{
				string pathName = cmdData.Application.ActiveUIDocument.Document.PathName;
				if (pathName == "")
				{
					MessageBox.Show("请先保存项目。");
					result = Autodesk.Revit.UI.Result.Cancelled;
				}
				else
				{
					cmdData.Application.Application.FailuresProcessing += this.OnFailuresProcessing;
					bool flag = false;
					bool isLinkModel = false;
					ConfigDataXMLSelectForm configDataXMLSelectForm = new ConfigDataXMLSelectForm(true);
					string str = XmlUtils.SplitPathName(pathName) + ".xml";
					configDataXMLSelectForm.FileName = Product.UserDataLocation + "\\" + str;
					if (configDataXMLSelectForm.ShowDialog() == DialogResult.OK)
					{
						UIApplication application = cmdData.Application;
						Document document = application.ActiveUIDocument.Document;
						DbOpeningBase.ClearTag(document);
						List<Duct> listRectDuct = CmdTools.FindRectDuct(document);
						CmdTools.FindRoundDuct(document);
						List<Pipe> listPipe = CmdTools.FindAllPipe(document);
						List<CableTray> listCableTray = CmdTools.FindAllCableTray(document);
						List<FamilyInstance> lstEquips = CmdTools.FindAllFireHydrant(document);
						List<LinkFile> linkFiles = LinkFile.GetLinkFiles(document);
						XYZ origin = new XYZ();
						string fileName = "";
						List<DbOpeningBase> list = new List<DbOpeningBase>();
						int projectId = 0;
						if (linkFiles.Count > 0)
						{
							isLinkModel = true;
						}
						if (!flag)
						{
							fileName = configDataXMLSelectForm.FileName;
							XmlUtils.CreateDataFile(fileName, document);
						}
						else
						{
							DbProject projectByCurrentDoc = DbProject.GetProjectByCurrentDoc(document);
							if (projectByCurrentDoc == null)
							{
								string text;
								if (RevitVersionFuncs.GetWorksharingCentralFilename(document) != "")
								{
									text = RevitVersionFuncs.GetWorksharingCentralFilename(document);
								}
								else
								{
									text = document.PathName;
								}
								MessageBox.Show("此模型未加入任何项目。\n请以当前文件(中心文件)路径：" + text + "为项目路径在协同项目管理器中新建一个项目。\n(路径已复制到剪切板)");
								Clipboard.SetDataObject(text);
								return Autodesk.Revit.UI.Result.Cancelled;
							}
							projectId = projectByCurrentDoc.Id;
						}
						try
						{
							if (!CmdOpeningToDb.DetectRectDuctOpening(application, document, listRectDuct, linkFiles, origin, list, projectId))
							{
								return Autodesk.Revit.UI.Result.Succeeded;
							}
							if (!CmdOpeningToDb.DetectPipeOpening(application, document, listPipe, linkFiles, origin, list, projectId))
							{
								return Autodesk.Revit.UI.Result.Succeeded;
							}
							if (!CmdOpeningToDb.DetectCableTrayOpening(application, document, listCableTray, linkFiles, origin, list, projectId))
							{
								return Autodesk.Revit.UI.Result.Succeeded;
							}
							if (!CmdOpeningToDb.DetectEquipOpening(application, document, lstEquips, linkFiles, origin, list, projectId))
							{
								return Autodesk.Revit.UI.Result.Succeeded;
							}
							CmdOpeningToDb.UpdateOpeningAxisXYData(list, document);
							ShowDlgApp.ThisApp.ShowDlgOpeningDetect(list, application, flag, isLinkModel, fileName);
							return Autodesk.Revit.UI.Result.Succeeded;
						}
						catch (Exception ex)
						{
							MessageBox.Show(ex.Message);
							return Autodesk.Revit.UI.Result.Succeeded;
						}
					}
					result = Autodesk.Revit.UI.Result.Cancelled;
				}
			}
			catch (Exception ex2)
			{
				MessageBox.Show(ex2.Message);
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			return result;
		}

		private List<DbOpeningBase> CheckInvalidOpeninInfo(UIApplication uiApp, string strXMLPath)
		{
			Document document = uiApp.ActiveUIDocument.Document;
			FileSystemInfo fileSystemInfo = new FileInfo(strXMLPath);
			List<DbOpeningBase> list = new List<DbOpeningBase>();
			List<DbOpeningBase> list2 = new List<DbOpeningBase>();
			if (fileSystemInfo.Exists)
			{
				try
				{
					string strDocFileName = XmlUtils.SplitPathName(document.PathName);
					XmlDocument xmlDocument = new XmlDocument();
					xmlDocument.Load(strXMLPath);
					foreach (object obj in XmlUtils.GetXmlItemNodeByFileName(xmlDocument, strDocFileName, true))
					{
						XmlNode xmlNode = (XmlNode)obj;
						string name = xmlNode.Name;
						if (!(name == "梁洞"))
						{
							if (!(name == "板洞"))
							{
								if (!(name == "墙洞"))
								{
									continue;
								}
								goto IL_12E;
							}
						}
						else
						{
							IEnumerator enumerator2 = xmlNode.GetEnumerator();
							{
								while (enumerator2.MoveNext())
								{
									object obj2 = enumerator2.Current;
									DbOpeningBase item = XmlUtils.ReadBeamOpening((XmlNode)obj2);
									list.Add(item);
								}
								continue;
							}
						}
						IEnumerator enumerator3 = xmlNode.GetEnumerator();
						{
							while (enumerator3.MoveNext())
							{
								object obj3 = enumerator3.Current;
								DbOpeningBase item = XmlUtils.ReadFloorOpening((XmlNode)obj3);
								list.Add(item);
							}
							continue;
						}
						IL_12E:
						foreach (object obj4 in xmlNode)
						{
							DbOpeningBase item = XmlUtils.ReadWallOpening((XmlNode)obj4);
							list.Add(item);
						}
					}
					ICollection<ElementId> collection = new FilteredElementCollector(document).OfClass(typeof(MEPCurve)).ToElementIds();
					foreach (DbOpeningBase dbOpeningBase in list)
					{
						if (dbOpeningBase.HostType != HostType.eBeam)
						{
							ElementId elementId = new ElementId(dbOpeningBase.PipeId);
							if (!collection.Contains(elementId))
							{
								dbOpeningBase.IsValid = false;
								list2.Add(dbOpeningBase);
							}
							else
							{
								MEPCurve mepcurve = document.GetElement(elementId) as MEPCurve;
								Curve curve = (mepcurve.Location as LocationCurve).Curve;
								if (!GeoUtil.IsEqual(curve.Distance(dbOpeningBase.Location), 1E-06))
								{
									dbOpeningBase.IsValid = false;
									list2.Add(dbOpeningBase);
								}
								else
								{
									Line.CreateBound(dbOpeningBase.PipeStartPoint, dbOpeningBase.PipeEndPoint);
									if (!curve.GetEndPoint(0).IsAlmostEqualTo(dbOpeningBase.PipeStartPoint) || !curve.GetEndPoint(1).IsAlmostEqualTo(dbOpeningBase.PipeEndPoint))
									{
										dbOpeningBase.IsValid = false;
										list2.Add(dbOpeningBase);
									}
									else
									{
										double d = 0.0;
										double d2 = 0.0;
										if (CmdTools.GetPipeSecSize(mepcurve, ref d, ref d2))
										{
											double d3 = AssistFunc.mmToFeet(dbOpeningBase.SectionParameter.Parameter2);
											double d4 = AssistFunc.mmToFeet(dbOpeningBase.SectionParameter.Parameter1);
											if (mepcurve is Pipe)
											{
												if (!GeoUtil.IsEqual(d, d4))
												{
													dbOpeningBase.IsValid = false;
													list2.Add(dbOpeningBase);
												}
											}
											else if (!GeoUtil.IsEqual(d, d3) || !GeoUtil.IsEqual(d2, d4))
											{
												dbOpeningBase.IsValid = false;
												list2.Add(dbOpeningBase);
											}
										}
									}
								}
							}
						}
					}
				}
				catch
				{
				}
			}
			return list2;
		}

		public static void UpdateOpeningAxisXYData(List<DbOpeningBase> lstOpenings, Autodesk.Revit.DB.Document doc)
		{
			List<Document> linkDocs = LinkFile.GetLinkDocs(doc);
			linkDocs.Insert(0, doc);
			List<Grid> list = new List<Grid>();
			foreach (Autodesk.Revit.DB.Document doc2 in linkDocs)
			{
				list = CmdOpeningToDb.GetDocAxisGrid(doc2);
				if (list.Count > 0)
				{
					break;
				}
			}
			if (list.Count == 0)
			{
				return;
			}
			List<CmdOpeningToDb.PointSort> list2 = new List<CmdOpeningToDb.PointSort>();
			int count = list.Count;
			for (int i = 0; i < count - 1; i++)
			{
				Grid grid = list[i];
				Curve curve = grid.Curve;
				for (int j = i + 1; j < count; j++)
				{
					Grid grid2 = list[j];
					if (!(grid.Name == grid2.Name))
					{
						Curve curve2 = grid2.Curve;
						IntersectionResultArray intersectionResultArray = null;
                        if ((int)curve.Intersect(curve2, out intersectionResultArray) == 8)
						{
							XYZ xyzpoint = intersectionResultArray.get_Item(0).XYZPoint;
							CmdOpeningToDb.PointSort pointSort = new CmdOpeningToDb.PointSort();
							pointSort.pt = new XYZ(xyzpoint.X, xyzpoint.Y, 0.0);
							if (CmdOpeningToDb.IsStringHaveAscII(grid.Name))
							{
								pointSort.m_lstGridName.Add(grid.Name);
								pointSort.m_lstGridName.Add(grid2.Name);
							}
							else
							{
								pointSort.m_lstGridName.Add(grid2.Name);
								pointSort.m_lstGridName.Add(grid.Name);
							}
							list2.Add(pointSort);
						}
					}
				}
			}
			if (list2 != null && list2.Count > 0)
			{
				foreach (DbOpeningBase dbOpeningBase in lstOpenings)
				{
					foreach (CmdOpeningToDb.PointSort pointSort2 in list2)
					{
						new XYZ(dbOpeningBase.Location.X, dbOpeningBase.Location.Y, 0.0);
						double param = pointSort2.pt.DistanceTo(dbOpeningBase.Location);
						pointSort2.param = param;
					}
					list2.Sort(new CmdOpeningToDb.PointComparer());
					dbOpeningBase.AxisX = list2[0].m_lstGridName[0];
					dbOpeningBase.AxisY = list2[0].m_lstGridName[1];
				}
			}
		}

		private static List<Grid> GetDocAxisGrid(Autodesk.Revit.DB.Document doc)
		{
			List<Grid> list = new List<Grid>();
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(Grid)).ToElements())
			{
				Grid grid = element as Grid;
				if (grid != null)
				{
					list.Add(grid);
				}
			}
			return list;
		}

		private static bool IsStringHaveAscII(string strVal)
		{
			try
			{
				foreach (char c in strVal)
				{
					if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		public static XYZ GetOpeningTagNormal(Wall wall, XYZ pt)
		{
			try
			{
				XYZ result = wall.Orientation;
				Arc arc = (wall.Location as LocationCurve).Curve as Arc;
				if (arc != null)
				{
					Plane planeProj = RevitVersionFuncs.CreatePlanByNormalAndOrigin(XYZ.BasisZ, XYZ.Zero);
					pt = CmdTools.CalcProjPointByPlane(pt, planeProj);
					XYZ xyz = CmdTools.CalcProjPointByPlane(arc.Center, planeProj);
					result = (pt - xyz).Normalize();
				}
				return result;
			}
			catch
			{
			}
			return null;
		}

		private static bool DetectCableTrayOpening(UIApplication uiApp, Autodesk.Revit.DB.Document doc, List<CableTray> listCableTray, List<LinkFile> fileList, XYZ origin, List<DbOpeningBase> ol, int projectId)
		{
			string mepfileName = XmlUtils.SplitPathName(doc.PathName);
			ProgressBarForm progressBarForm = new ProgressBarForm(listCableTray.Count, ProgressBarStyle.Blocks, true);
			progressBarForm.Text = "桥架碰撞检测";
			progressBarForm.Show();
			foreach (CableTray cableTray in listCableTray)
			{
				double num = 0.0;
				double num2 = 0.0;
				if (CmdTools.GetPipeSecSize(cableTray, ref num, ref num2))
				{
					num = AssistFunc.feetToMM(num);
					num2 = AssistFunc.feetToMM(num2);
					List<Wall> list = CmdTools.FindCableTrayWallLink(doc, cableTray, origin);
					foreach (LinkFile linkFile in fileList)
					{
						Document doc2 = uiApp.Application.OpenDocumentFile(linkFile.FileName);
						list.AddRange(CmdTools.FindCableTrayWallLink(doc2, cableTray, origin));
					}
					foreach (LinkFile linkFile2 in fileList)
					{
                        if ((int)linkFile2.FlieType == 1)
						{
							Document doc3 = uiApp.Application.OpenDocumentFile(linkFile2.FileName);
							list.AddRange(CmdTools.FindCableTrayWallLink(doc3, cableTray, origin));
						}
					}
					foreach (Wall wall in list)
					{
						if ((int)wall.WallType.Kind != 2 && (int)wall.WallType.Kind != 1)
						{
							foreach (Face face in CmdTools.GetWallFace(wall))
							{
								if (!(null == face))
								{
									Line curve = CmdTools.FindCableTrayLine(cableTray);
									Line line = YJKLineEx.YJKGetBound(curve.GetEndPoint(0) - origin, curve.GetEndPoint(1) - origin);
									foreach (XYZ xyz in CmdTools.LineIntersectFace(face, line))
									{
										if (xyz != null)
										{
											SectionParameter sp = new SectionParameter(num2, num);
											RectOutSize rectOutSize = XmlUtils.GetRectOutSize(CutType.eBridge, HostType.eArchWall);
											BoxParameter bp = new BoxParameter(rectOutSize.Top, rectOutSize.Bottom, rectOutSize.Left, rectOutSize.Right);
											if (wall.get_Parameter(BuiltInParameter.WALL_STRUCTURAL_SIGNIFICANT).AsInteger() == 0)
											{
											}
											HostType hType = CmdTools.IsPrimaryStructure(wall.Id, doc) ? HostType.eStruWall : HostType.eArchWall;
											DbWallToBeOpened dbWallToBeOpened = new DbWallToBeOpened(projectId, xyz, wall.Id.IntegerValue, cableTray.Id.IntegerValue, sp, bp, CutType.eBridge, hType, wall.GetYJKLevel().Name);
											dbWallToBeOpened.Status = CmdTools.GetStatus(uiApp, cableTray, doc, origin, xyz);
											dbWallToBeOpened.MEPFileName = mepfileName;
											dbWallToBeOpened.OpeningID = ElementId.InvalidElementId;
											dbWallToBeOpened.PipeStartPoint = curve.GetEndPoint(0);
											dbWallToBeOpened.PipeEndPoint = curve.GetEndPoint(1);
											dbWallToBeOpened.dWallWidth = wall.WallType.Width;
											dbWallToBeOpened.vtWallOrient = CmdOpeningToDb.GetOpeningTagNormal(wall, xyz);
											if (!ol.Contains(dbWallToBeOpened))
											{
												ol.Add(dbWallToBeOpened);
											}
										}
									}
								}
							}
						}
					}
					List<Floor> list2 = CmdTools.FindCableTrayFloorLink(doc, cableTray, origin);
					foreach (LinkFile linkFile3 in fileList)
					{
                        if ((int)linkFile3.FlieType == 1)
						{
							Document doc4 = uiApp.Application.OpenDocumentFile(linkFile3.FileName);
							list2.AddRange(CmdTools.FindCableTrayFloorLink(doc4, cableTray, origin));
						}
					}
					foreach (Floor floor in list2)
					{
						Face face2 = CmdTools.FindFloorFace(floor);
						if (!(null == face2))
						{
							double mepcurveAng2Floor = CmdTools.GetMEPCurveAng2Floor(cableTray, floor);
							Line curve2 = CmdTools.FindCableTrayLine(cableTray);
							Line line2 = YJKLineEx.YJKGetBound(curve2.GetEndPoint(0) - origin, curve2.GetEndPoint(1) - origin);
							foreach (XYZ xyz2 in CmdTools.LineIntersectFace(face2, line2))
							{
								if (xyz2 != null)
								{
									SectionParameter sp2 = new SectionParameter(num2, num);
									RectOutSize rectOutSize2 = XmlUtils.GetRectOutSize(CutType.eBridge, HostType.eFloor);
									BoxParameter bp2 = new BoxParameter(rectOutSize2.Top, rectOutSize2.Bottom, rectOutSize2.Left, rectOutSize2.Right);
									DbFloorToBeOpened dbFloorToBeOpened = new DbFloorToBeOpened(projectId, xyz2, floor.Id.IntegerValue, cableTray.Id.IntegerValue, sp2, bp2, CutType.eBridge, HostType.eFloor, floor.GetYJKLevel().Name);
									dbFloorToBeOpened.Status = CmdTools.GetStatus(uiApp, cableTray, doc, origin, xyz2);
									dbFloorToBeOpened.MEPFileName = mepfileName;
									dbFloorToBeOpened.OpeningID = ElementId.InvalidElementId;
									dbFloorToBeOpened.PipeStartPoint = curve2.GetEndPoint(0);
									dbFloorToBeOpened.PipeEndPoint = curve2.GetEndPoint(1);
									dbFloorToBeOpened.PipeConnAxisXOnSectionPlaneAng = mepcurveAng2Floor;
									if (!ol.Contains(dbFloorToBeOpened))
									{
										ol.Add(dbFloorToBeOpened);
									}
								}
							}
						}
					}
					List<FamilyInstance> list3 = CmdTools.FindElementIntersectBeam(cableTray, doc, origin);
					foreach (LinkFile linkFile4 in fileList)
					{
						Document doc5 = uiApp.Application.OpenDocumentFile(linkFile4.FileName);
						list3.AddRange(CmdTools.FindElementIntersectBeam(cableTray, doc5, origin));
					}
					foreach (FamilyInstance familyInstance in list3)
					{
						List<Face> list4 = CmdTools.FindBeamFace(familyInstance);
						if (list4.Count != 0)
						{
							Line line3 = CmdTools.FindCableTrayLine(cableTray);
							if (!(line3 == null))
							{
								XYZ xyz3 = CmdTools.LineIntersectPlaneFace(list4[0], line3);
								if (xyz3 != null)
								{
									SectionParameter sp3 = new SectionParameter(num2, num);
									RectOutSize rectOutSize3 = XmlUtils.GetRectOutSize(CutType.eBridge, HostType.eBeam);
									BoxParameter bp3 = new BoxParameter(rectOutSize3.Top, rectOutSize3.Bottom, rectOutSize3.Left, rectOutSize3.Right);
									Level level = familyInstance.Host as Level;
									string level2;
									if (level != null)
									{
										level2 = level.Name;
									}
									else
									{
										level2 = familyInstance.GetParameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM).AsValueString();
									}
									DbBeamToBeOpened dbBeamToBeOpened = new DbBeamToBeOpened(projectId, xyz3, familyInstance.Id.IntegerValue, cableTray.Id.IntegerValue, sp3, bp3, CutType.eBridge, HostType.eBeam, level2);
									dbBeamToBeOpened.Status = OpeningStatus.Unopen;
									dbBeamToBeOpened.MEPFileName = mepfileName;
									dbBeamToBeOpened.OpeningID = ElementId.InvalidElementId;
									dbBeamToBeOpened.PipeStartPoint = line3.GetEndPoint(0);
									dbBeamToBeOpened.PipeEndPoint = line3.GetEndPoint(1);
									if (!ol.Contains(dbBeamToBeOpened))
									{
										ol.Add(dbBeamToBeOpened);
									}
								}
							}
						}
					}
					progressBarForm.RefreshProgressBar();
					if (progressBarForm.m_stopTag)
					{
						return false;
					}
				}
			}
			progressBarForm.Dispose();
			return true;
		}

		private static bool DetectPipeOpening(UIApplication uiApp, Autodesk.Revit.DB.Document doc, List<Pipe> listPipe, List<LinkFile> fileList, XYZ origin, List<DbOpeningBase> ol, int projectId)
		{
			string mepfileName = XmlUtils.SplitPathName(doc.PathName);
			ProgressBarForm progressBarForm = new ProgressBarForm(listPipe.Count, ProgressBarStyle.Blocks, true);
			progressBarForm.Text = "水管碰撞检测";
			progressBarForm.Show();
			try
			{
				foreach (Pipe pipe in listPipe)
				{
					List<Wall> list = CmdTools.FindPipeWallLink(doc, pipe, origin);
					foreach (LinkFile linkFile in fileList)
					{
						try
						{
							Document doc2 = uiApp.Application.OpenDocumentFile(linkFile.FileName);
							list.AddRange(CmdTools.FindPipeWallLink(doc2, pipe, origin));
						}
						catch (Exception ex)
						{
							MessageBox.Show(ex.Message);
						}
					}
					foreach (Wall wall in list)
					{
						try
						{
							if ((int)wall.WallType.Kind != 2 && (int)wall.WallType.Kind != 1)
							{
								Line line = CmdTools.FindPipeLine(pipe);
								foreach (XYZ xyz in CmdTools.GetCvIntersect2WallPoints(line, wall))
								{
									try
									{
										if (xyz != null)
										{
											SectionParameter sp = new SectionParameter(CmdTools.GetPipeSpec(pipe));
											BoxParameter bp = new BoxParameter(XmlUtils.GetCircleOutSize(CutType.ePipe, HostType.eArchWall));
											if (wall.get_Parameter(BuiltInParameter.WALL_STRUCTURAL_SIGNIFICANT).AsInteger() == 0)
											{
											}
											HostType hType = CmdTools.IsPrimaryStructure(wall.Id, doc) ? HostType.eStruWall : HostType.eArchWall;
											ol.Add(new DbWallToBeOpened(projectId, xyz, wall.Id.IntegerValue, pipe.Id.IntegerValue, sp, bp, CutType.ePipe, hType, wall.GetYJKLevel().Name)
											{
												Status = CmdTools.GetStatus(uiApp, pipe, doc, origin, xyz),
												MEPFileName = mepfileName,
												OpeningID = ElementId.InvalidElementId,
												PipeStartPoint = line.GetEndPoint(0),
												PipeEndPoint = line.GetEndPoint(1),
												dWallWidth = wall.WallType.Width,
												vtWallOrient = CmdOpeningToDb.GetOpeningTagNormal(wall, xyz)
											});
										}
									}
									catch (Exception ex2)
									{
										MessageBox.Show(ex2.Message);
									}
								}
							}
						}
						catch (Exception)
						{
						}
					}
					List<Floor> list2 = CmdTools.FindPipeFloorLink(doc, pipe, origin);
					foreach (LinkFile linkFile2 in fileList)
					{
						Document doc3 = uiApp.Application.OpenDocumentFile(linkFile2.FileName);
						list2.AddRange(CmdTools.FindPipeFloorLink(doc3, pipe, origin));
					}
					foreach (Floor floor in list2)
					{
						double mepcurveAng2Floor = CmdTools.GetMEPCurveAng2Floor(pipe, floor);
						Face face = CmdTools.FindFloorFace(floor);
						if (!(null == face))
						{
							Line line2 = CmdTools.FindPipeLine(pipe);
							foreach (XYZ xyz2 in CmdTools.LineIntersectFace(face, line2))
							{
								if (xyz2 != null)
								{
									SectionParameter sp2 = new SectionParameter(CmdTools.GetPipeSpec(pipe));
									BoxParameter bp2 = new BoxParameter(XmlUtils.GetCircleOutSize(CutType.ePipe, HostType.eFloor));
									DbFloorToBeOpened dbFloorToBeOpened = new DbFloorToBeOpened(projectId, xyz2, floor.Id.IntegerValue, pipe.Id.IntegerValue, sp2, bp2, CutType.ePipe, HostType.eFloor, floor.GetYJKLevel().Name);
									dbFloorToBeOpened.Status = CmdTools.GetStatus(uiApp, pipe, doc, origin, xyz2);
									dbFloorToBeOpened.MEPFileName = mepfileName;
									dbFloorToBeOpened.OpeningID = ElementId.InvalidElementId;
									dbFloorToBeOpened.PipeStartPoint = line2.GetEndPoint(0);
									dbFloorToBeOpened.PipeEndPoint = line2.GetEndPoint(1);
									dbFloorToBeOpened.PipeConnAxisXOnSectionPlaneAng = mepcurveAng2Floor;
									if (!ol.Contains(dbFloorToBeOpened))
									{
										ol.Add(dbFloorToBeOpened);
									}
								}
							}
						}
					}
					List<FamilyInstance> list3 = CmdTools.FindElementIntersectBeam(pipe, doc, origin);
					foreach (LinkFile linkFile3 in fileList)
					{
						Document doc4 = uiApp.Application.OpenDocumentFile(linkFile3.FileName);
						list3.AddRange(CmdTools.FindElementIntersectBeam(pipe, doc4, origin));
					}
					foreach (FamilyInstance familyInstance in list3)
					{
						List<Face> list4 = CmdTools.FindBeamFace(familyInstance);
						if (list4.Count != 0)
						{
							Line line3 = CmdTools.FindPipeLine(pipe);
							if (!(line3 == null))
							{
								XYZ xyz3 = CmdTools.LineIntersectPlaneFace(list4[0], line3);
								if (xyz3 == null)
								{
									Line line4 = (familyInstance.Location as LocationCurve).Curve as Line;
									if (line4 == null)
									{
										continue;
									}
									xyz3 = line4.Project(line3.Project(line4.GetEndPoint(0)).XYZPoint).XYZPoint;
									if (xyz3 == null)
									{
										continue;
									}
								}
								SectionParameter sp3 = new SectionParameter(CmdTools.GetPipeSpec(pipe));
								BoxParameter bp3 = new BoxParameter(XmlUtils.GetCircleOutSize(CutType.ePipe, HostType.eBeam));
								Level level = familyInstance.Host as Level;
								string level2;
								if (level != null)
								{
									level2 = level.Name;
								}
								else
								{
									level2 = familyInstance.GetParameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM).AsValueString();
								}
								DbBeamToBeOpened dbBeamToBeOpened = new DbBeamToBeOpened(projectId, xyz3, familyInstance.Id.IntegerValue, pipe.Id.IntegerValue, sp3, bp3, CutType.ePipe, HostType.eBeam, level2);
								dbBeamToBeOpened.MEPFileName = mepfileName;
								dbBeamToBeOpened.OpeningID = ElementId.InvalidElementId;
								dbBeamToBeOpened.PipeStartPoint = line3.GetEndPoint(0);
								dbBeamToBeOpened.PipeEndPoint = line3.GetEndPoint(1);
								dbBeamToBeOpened.Status = OpeningStatus.Unopen;
								if (!ol.Contains(dbBeamToBeOpened))
								{
									ol.Add(dbBeamToBeOpened);
								}
							}
						}
					}
					progressBarForm.RefreshProgressBar();
					if (progressBarForm.m_stopTag)
					{
						return false;
					}
				}
			}
			catch (Exception)
			{
			}
			progressBarForm.Dispose();
			return true;
		}

		private static void DetectRoundDuctOpening(UIApplication uiApp, Autodesk.Revit.DB.Document doc, List<Duct> listRoundDuct, List<LinkFile> fileList, XYZ origin, List<DbOpeningBase> ol, int projectId)
		{
			string mepfileName = XmlUtils.SplitPathName(doc.PathName);
			ProgressBarForm progressBarForm = new ProgressBarForm(listRoundDuct.Count, ProgressBarStyle.Blocks, true);
			progressBarForm.Text = "风管碰撞检测";
			progressBarForm.Show();
			foreach (Duct duct in listRoundDuct)
			{
				List<Wall> list = CmdTools.FindDuctWallLink(duct, doc, origin);
				foreach (LinkFile linkFile in fileList)
				{
                    if ((int)linkFile.FlieType == 1)
					{
						Document docLink = uiApp.Application.OpenDocumentFile(linkFile.FileName);
						list.AddRange(CmdTools.FindDuctWallLink(duct, docLink, origin));
					}
				}
				foreach (Wall wall in list)
				{
					if ((int)wall.WallType.Kind != 2 && (int)wall.WallType.Kind != 1)
					{
						foreach (Face face in CmdTools.GetWallFace(wall))
						{
							if (!(null == face))
							{
								Line ductLine = CmdTools.GetDuctLine(duct);
								YJKLineEx.YJKGetBound(ductLine.GetEndPoint(0) - origin, ductLine.GetEndPoint(1) - origin);
								foreach (XYZ xyz in CmdTools.LineIntersectFace(face, ductLine))
								{
									if (xyz != null)
									{
										SectionParameter sp = new SectionParameter(CmdTools.GetDuctSpec(duct) / 2.0);
										BoxParameter bp = new BoxParameter(XmlUtils.GetCircleOutSize(CutType.eDuct, HostType.eArchWall));
										if (wall.get_Parameter(BuiltInParameter.WALL_STRUCTURAL_SIGNIFICANT).AsInteger() == 0)
										{
										}
										HostType hType = CmdTools.IsPrimaryStructure(wall.Id, doc) ? HostType.eStruWall : HostType.eArchWall;
										DbWallToBeOpened dbWallToBeOpened = new DbWallToBeOpened(projectId, xyz, wall.Id.IntegerValue, duct.Id.IntegerValue, sp, bp, CutType.eDuct, hType, wall.GetYJKLevel().Name);
										dbWallToBeOpened.Status = CmdTools.GetStatus(uiApp, duct, doc, origin, xyz);
										dbWallToBeOpened.MEPFileName = mepfileName;
										dbWallToBeOpened.OpeningID = ElementId.InvalidElementId;
										dbWallToBeOpened.PipeStartPoint = ductLine.GetEndPoint(0);
										dbWallToBeOpened.PipeEndPoint = ductLine.GetEndPoint(1);
										dbWallToBeOpened.dWallWidth = wall.WallType.Width;
										dbWallToBeOpened.vtWallOrient = CmdOpeningToDb.GetOpeningTagNormal(wall, xyz);
										if (!ol.Contains(dbWallToBeOpened))
										{
											ol.Add(dbWallToBeOpened);
										}
									}
								}
							}
						}
					}
				}
				List<Floor> list2 = CmdTools.FindDuctFloorLink(duct, doc, origin);
				foreach (LinkFile linkFile2 in fileList)
				{
					Document docLink2 = uiApp.Application.OpenDocumentFile(linkFile2.FileName);
					list2.AddRange(CmdTools.FindDuctFloorLink(duct, docLink2, origin));
				}
				foreach (Floor floor in list2)
				{
					double mepcurveAng2Floor = CmdTools.GetMEPCurveAng2Floor(duct, floor);
					Face face2 = CmdTools.FindFloorFace(floor);
					if (!(null == face2))
					{
						Line ductLine2 = CmdTools.GetDuctLine(duct);
						foreach (XYZ xyz2 in CmdTools.LineIntersectFace(face2, ductLine2))
						{
							if (xyz2 != null)
							{
								SectionParameter sp2 = new SectionParameter(CmdTools.GetDuctSpec(duct) / 2.0);
								BoxParameter bp2 = new BoxParameter(XmlUtils.GetCircleOutSize(CutType.eDuct, HostType.eFloor));
								DbFloorToBeOpened dbFloorToBeOpened = new DbFloorToBeOpened(projectId, xyz2, floor.Id.IntegerValue, duct.Id.IntegerValue, sp2, bp2, CutType.eDuct, HostType.eFloor, floor.GetYJKLevel().Name);
								dbFloorToBeOpened.Status = CmdTools.GetStatus(uiApp, duct, doc, origin, xyz2);
								dbFloorToBeOpened.MEPFileName = mepfileName;
								dbFloorToBeOpened.OpeningID = ElementId.InvalidElementId;
								dbFloorToBeOpened.PipeStartPoint = ductLine2.GetEndPoint(0);
								dbFloorToBeOpened.PipeEndPoint = ductLine2.GetEndPoint(1);
								dbFloorToBeOpened.PipeConnAxisXOnSectionPlaneAng = mepcurveAng2Floor;
								if (!ol.Contains(dbFloorToBeOpened))
								{
									ol.Add(dbFloorToBeOpened);
								}
							}
						}
					}
				}
				List<FamilyInstance> list3 = CmdTools.FindElementIntersectBeam(duct, doc, origin);
				foreach (LinkFile linkFile3 in fileList)
				{
					Document doc2 = uiApp.Application.OpenDocumentFile(linkFile3.FileName);
					list3.AddRange(CmdTools.FindElementIntersectBeam(duct, doc2, origin));
				}
				foreach (FamilyInstance familyInstance in list3)
				{
					List<Face> list4 = CmdTools.FindBeamFace(familyInstance);
					if (list4.Count != 0)
					{
						Line ductLine3 = CmdTools.GetDuctLine(duct);
						if (!(ductLine3 == null))
						{
							XYZ xyz3 = CmdTools.LineIntersectPlaneFace(list4[0], ductLine3);
							if (xyz3 != null)
							{
								SectionParameter sp3 = new SectionParameter(CmdTools.GetDuctSpec(duct) / 2.0);
								BoxParameter bp3 = new BoxParameter(XmlUtils.GetCircleOutSize(CutType.eDuct, HostType.eBeam));
								Level level = familyInstance.Host as Level;
								string level2;
								if (level != null)
								{
									level2 = level.Name;
								}
								else
								{
									level2 = familyInstance.GetParameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM).AsValueString();
								}
								DbBeamToBeOpened dbBeamToBeOpened = new DbBeamToBeOpened(projectId, xyz3, familyInstance.Id.IntegerValue, duct.Id.IntegerValue, sp3, bp3, CutType.eDuct, HostType.eBeam, level2);
								dbBeamToBeOpened.Status = OpeningStatus.Unopen;
								dbBeamToBeOpened.MEPFileName = mepfileName;
								dbBeamToBeOpened.OpeningID = ElementId.InvalidElementId;
								dbBeamToBeOpened.PipeStartPoint = ductLine3.GetEndPoint(0);
								dbBeamToBeOpened.PipeEndPoint = ductLine3.GetEndPoint(1);
								if (!ol.Contains(dbBeamToBeOpened))
								{
									ol.Add(dbBeamToBeOpened);
								}
							}
						}
					}
				}
				progressBarForm.RefreshProgressBar();
				if (progressBarForm.m_stopTag)
				{
					return;
				}
			}
			progressBarForm.Dispose();
		}

		private static bool DetectRectDuctOpening(UIApplication uiApp, Autodesk.Revit.DB.Document doc, List<Duct> listRectDuct, List<LinkFile> fileList, XYZ origin, List<DbOpeningBase> ol, int projectId)
		{
			string mepfileName = XmlUtils.SplitPathName(doc.PathName);
			ProgressBarForm progressBarForm = new ProgressBarForm(listRectDuct.Count, ProgressBarStyle.Blocks, true);
			progressBarForm.Text = "风管碰撞检测";
			progressBarForm.Show();
			foreach (Duct duct in listRectDuct)
			{
				List<Wall> list = null;
				try
				{
					list = CmdTools.FindDuctWallLink(duct, doc, origin);
					foreach (LinkFile linkFile in fileList)
					{
						Document docLink = uiApp.Application.OpenDocumentFile(linkFile.FileName);
						list.AddRange(CmdTools.FindDuctWallLink(duct, docLink, origin));
					}
				}
				catch (Exception ex)
				{
					string message = ex.Message;
				}
				try
				{
					foreach (Wall wall in list)
					{
						if ((int)wall.WallType.Kind != 2 && (int)wall.WallType.Kind != 1)
						{
							Line ductLine = CmdTools.GetDuctLine(duct);
							foreach (XYZ xyz in CmdTools.GetCvIntersect2WallPoints(ductLine, wall))
							{
								if (xyz != null)
								{
									double ductWidth = CmdTools.GetDuctWidth(duct, doc);
									SectionParameter sp = new SectionParameter(CmdTools.GetDuctHeight(duct, doc), ductWidth);
									RectOutSize rectOutSize = XmlUtils.GetRectOutSize(CutType.eDuct, HostType.eArchWall);
									BoxParameter bp = new BoxParameter(rectOutSize.Top, rectOutSize.Bottom, rectOutSize.Left, rectOutSize.Right);
									if (wall.get_Parameter(BuiltInParameter.WALL_STRUCTURAL_SIGNIFICANT).AsInteger() == 0)
									{
									}
									HostType hType = CmdTools.IsPrimaryStructure(wall.Id, doc) ? HostType.eStruWall : HostType.eArchWall;
									DbWallToBeOpened dbWallToBeOpened = new DbWallToBeOpened(projectId, xyz, wall.Id.IntegerValue, duct.Id.IntegerValue, sp, bp, CutType.eDuct, hType, wall.GetYJKLevel().Name);
									dbWallToBeOpened.Status = CmdTools.GetStatus(uiApp, duct, doc, origin, xyz);
									dbWallToBeOpened.MEPFileName = mepfileName;
									dbWallToBeOpened.OpeningID = ElementId.InvalidElementId;
									dbWallToBeOpened.PipeStartPoint = ductLine.GetEndPoint(0);
									dbWallToBeOpened.PipeEndPoint = ductLine.GetEndPoint(1);
									dbWallToBeOpened.dWallWidth = wall.WallType.Width;
									dbWallToBeOpened.vtWallOrient = CmdOpeningToDb.GetOpeningTagNormal(wall, xyz);
									if (!ol.Contains(dbWallToBeOpened))
									{
										ol.Add(dbWallToBeOpened);
									}
								}
							}
						}
					}
				}
				catch (Exception ex2)
				{
					string message2 = ex2.Message;
				}
				List<Floor> list2 = null;
				try
				{
					list2 = CmdTools.FindDuctFloorLink(duct, doc, origin);
					foreach (LinkFile linkFile2 in fileList)
					{
						Document docLink2 = uiApp.Application.OpenDocumentFile(linkFile2.FileName);
						list2.AddRange(CmdTools.FindDuctFloorLink(duct, docLink2, origin));
					}
				}
				catch (Exception ex3)
				{
					string message3 = ex3.Message;
				}
				try
				{
					foreach (Floor floor in list2)
					{
						double mepcurveAng2Floor = CmdTools.GetMEPCurveAng2Floor(duct, floor);
						Face face = CmdTools.FindFloorFace(floor);
						if (!(null == face))
						{
							Line ductLine2 = CmdTools.GetDuctLine(duct);
							foreach (XYZ xyz2 in CmdTools.LineIntersectFace(face, ductLine2))
							{
								if (xyz2 != null)
								{
									double ductWidth2 = CmdTools.GetDuctWidth(duct, doc);
									SectionParameter sp2 = new SectionParameter(CmdTools.GetDuctHeight(duct, doc), ductWidth2);
									RectOutSize rectOutSize2 = XmlUtils.GetRectOutSize(CutType.eDuct, HostType.eFloor);
									BoxParameter bp2 = new BoxParameter(rectOutSize2.Top, rectOutSize2.Bottom, rectOutSize2.Left, rectOutSize2.Right);
									DbFloorToBeOpened dbFloorToBeOpened = new DbFloorToBeOpened(projectId, xyz2, floor.Id.IntegerValue, duct.Id.IntegerValue, sp2, bp2, CutType.eDuct, HostType.eFloor, floor.GetYJKLevel().Name);
									dbFloorToBeOpened.Status = CmdTools.GetStatus(uiApp, duct, doc, origin, xyz2);
									dbFloorToBeOpened.MEPFileName = mepfileName;
									dbFloorToBeOpened.OpeningID = ElementId.InvalidElementId;
									dbFloorToBeOpened.PipeStartPoint = ductLine2.GetEndPoint(0);
									dbFloorToBeOpened.PipeEndPoint = ductLine2.GetEndPoint(1);
									dbFloorToBeOpened.PipeConnAxisXOnSectionPlaneAng = mepcurveAng2Floor;
									if (!ol.Contains(dbFloorToBeOpened))
									{
										ol.Add(dbFloorToBeOpened);
									}
								}
							}
						}
					}
				}
				catch (Exception ex4)
				{
					string message4 = ex4.Message;
				}
				List<FamilyInstance> list3 = null;
				try
				{
					list3 = CmdTools.FindElementIntersectBeam(duct, doc, origin);
					foreach (LinkFile linkFile3 in fileList)
					{
						Document doc2 = uiApp.Application.OpenDocumentFile(linkFile3.FileName);
						list3.AddRange(CmdTools.FindElementIntersectBeam(duct, doc2, origin));
					}
				}
				catch (Exception ex5)
				{
					string message5 = ex5.Message;
				}
				try
				{
					foreach (FamilyInstance familyInstance in list3)
					{
						List<Face> list4 = CmdTools.FindBeamFace(familyInstance);
						if (list4.Count != 0)
						{
							Line ductLine3 = CmdTools.GetDuctLine(duct);
							if (!(ductLine3 == null))
							{
								XYZ xyz3 = CmdTools.LineIntersectPlaneFace(list4[0], ductLine3);
								if (xyz3 != null)
								{
									double ductWidth3 = CmdTools.GetDuctWidth(duct, doc);
									SectionParameter sp3 = new SectionParameter(CmdTools.GetDuctHeight(duct, doc), ductWidth3);
									RectOutSize rectOutSize3 = XmlUtils.GetRectOutSize(CutType.eDuct, HostType.eBeam);
									BoxParameter bp3 = new BoxParameter(rectOutSize3.Top, rectOutSize3.Bottom, rectOutSize3.Left, rectOutSize3.Right);
									Level level = familyInstance.Host as Level;
									string level2;
									if (level != null)
									{
										level2 = level.Name;
									}
									else
									{
										level2 = familyInstance.GetParameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM).AsValueString();
									}
									DbBeamToBeOpened dbBeamToBeOpened = new DbBeamToBeOpened(projectId, xyz3, familyInstance.Id.IntegerValue, duct.Id.IntegerValue, sp3, bp3, CutType.eDuct, HostType.eBeam, level2);
									dbBeamToBeOpened.Status = OpeningStatus.Unopen;
									dbBeamToBeOpened.MEPFileName = mepfileName;
									dbBeamToBeOpened.OpeningID = ElementId.InvalidElementId;
									dbBeamToBeOpened.PipeStartPoint = ductLine3.GetEndPoint(0);
									dbBeamToBeOpened.PipeEndPoint = ductLine3.GetEndPoint(1);
									if (!ol.Contains(dbBeamToBeOpened))
									{
										ol.Add(dbBeamToBeOpened);
									}
								}
							}
						}
					}
				}
				catch (Exception ex6)
				{
					string message6 = ex6.Message;
				}
				progressBarForm.RefreshProgressBar();
				if (progressBarForm.m_stopTag)
				{
					return false;
				}
			}
			progressBarForm.Dispose();
			return true;
		}

		private static bool DetectEquipOpening(UIApplication uiApp, Autodesk.Revit.DB.Document doc, List<FamilyInstance> lstEquips, List<LinkFile> fileList, XYZ origin, List<DbOpeningBase> ol, int projectId)
		{
			XmlUtils.SplitPathName(doc.PathName);
			ProgressBarForm progressBarForm = new ProgressBarForm(lstEquips.Count, ProgressBarStyle.Blocks, true);
			progressBarForm.Text = "设备碰撞检测";
			progressBarForm.Show();
			foreach (FamilyInstance fiEquip in lstEquips)
			{
				List<Wall> list = null;
				try
				{
					list = CmdTools.FindEquipWallLink(fiEquip, doc);
					foreach (LinkFile linkFile in fileList)
					{
						Document doc2 = uiApp.Application.OpenDocumentFile(linkFile.FileName);
						list.AddRange(CmdTools.FindEquipWallLink(fiEquip, doc2));
					}
					foreach (Wall wall in list)
					{
						DbOpeningBase dbOpeningBase = CmdTools.CreateEquipWallOpening(wall, fiEquip);
						if (dbOpeningBase != null)
						{
							ol.Add(dbOpeningBase);
						}
					}
				}
				catch (Exception)
				{
				}
				progressBarForm.RefreshProgressBar();
				if (progressBarForm.m_stopTag)
				{
					return false;
				}
			}
			progressBarForm.Dispose();
			return true;
		}

		public static WindowHandle _hWndRevit;

		public class PointSort
		{
			public PointSort()
			{
				this.m_lstGridName = new List<string>();
				this.param = 0.0;
				this.pt = XYZ.Zero;
			}

			public XYZ pt;

			public double param;

			public List<string> m_lstGridName;
		}

		public class PointComparer : IComparer<CmdOpeningToDb.PointSort>
		{
			int IComparer<CmdOpeningToDb.PointSort>.Compare(CmdOpeningToDb.PointSort first, CmdOpeningToDb.PointSort second)
			{
				if (GeoUtil.IsEqual(first.param, second.param))
				{
					return 0;
				}
				if (first.param <= second.param)
				{
					return -1;
				}
				return 1;
			}
		}
	}
}
